/*
 * NetRayt
 * Copyright (c) 2007-2008 Maciej Nabozny.
 *
 * NetRayt is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * NetRayt is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with NetRayt; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef _CONN_FUNC_H
#define _CONN_FUNC_H

#include "conn.h"
#include "connFunc.h"

/*******************************************/
/*           Funkcje obsługujące klienta   */
/*******************************************/

connFunc::connFunc() {
}

/*
 * Odsyła błąd
 */
void connFunc::say_error(QString errName) {
	qDebug(errName.toAscii());
}

/*
 * Przyjęcie żądania
 */
void connFunc::getRequest(argList list, QString filename) {
	// sprawdz co chce klient...
	if (list.read("type") == "getinfo") {
		sendInfo();
	} else if (list.read("type") == "sendscene") {
		// Odebranie pliku ze sceną
		getScene(list, filename);
	} else if (list.read("type") == "sendtex") {
		// Odebranie pliku z teksturą
		getTex(list, filename);
	} else if (list.read("type") == "startrender") {
		// Rozpoczęcie raytracingu
		startRaytracer(list, filename);
	} else {
		argList resp;
		resp.set("msg", "Bad request");
	}
}

/*
 * Wysyła informacje o komputerze (narazie ustawione na stałe)
 */
void connFunc::sendInfo() {
	argList resp;
	
	resp.set("type", "getinfo");
	resp.set("cpuc", QString("%1").arg(cpucV));
	resp.set("cpuf", QString("%1").arg(cpufV));
	resp.set("mem", QString("%1").arg(memV));
	resp.set("yafray", "1");
	resp.set("indigo", "0");
	resp.set("blender", "0");
	
	emit(sendResponse(resp, ""));
}

/*
 * Odebranie pliku ze sceną
 */
void connFunc::getScene(argList list, QString filename) {
	raytracer = list.read("raytracer");
	scene = filename;
	
	// Odpowiedz
	argList resp;
	resp.set("msg", "ok");
	resp.set("type", "sendscene");
	emit(sendResponse(resp, ""));
}

/*
 * Odebranie pliku z teksturą
 */
void connFunc::getTex(argList list, QString filename) {
	// Dopisz plik do listy
	int texNum = textures.size();
	textures.append(list.read("path"));
	myTextures.append(filename);
	
	// Odpowiedz
	argList resp;
	resp.set("msg", "ok");
	resp.set("type", "sendscene");
	resp.set("num", QString("%1").arg(texNum));
	
	emit(sendResponse(resp, ""));
}

void connFunc::startRaytracer(argList list, QString filename) {
	raytracer = list.read("raytracer");
	if (raytracer == "yafray") {
		yafray_prepareFile();
		yafray(list);
	}
}

/*******************************************/
/*            Obsluga raytracerow          */
/*******************************************/

/*
 * Uruchomienie yafraya
 */
void connFunc::yafray(argList list) {
	// Lista argumentow yafraya
	QStringList yafray_arg;
	
	// Obszar obrazka
	yafray_arg.append("-r");
	yafray_arg.append(QString("%1:%2:%3:%4").arg(list.read("x1")).arg(list.read("x2")).arg(list.read("y1")).arg(list.read("y2")));
	
	// Strategia raytracingu
	yafray_arg.append("-s");
	yafray_arg.append("threaded");
	
	// Ilosc watkow
	yafray_arg.append("-c");
	yafray_arg.append(QString("%1").arg(cpucV));
	
	// Plik ze sceną
	yafray_arg.append(scene);

	// Uruchomienie yafray'a
	qDebug(QString("connFunc::yafray: Parametry yafraya: %1").arg(yafray_arg.join(", ")).toAscii());
	QProcess::execute(yafray_path, yafray_arg);
	
	// Odeslanie sceny
	qDebug("connFunc::yafray: Raytracing zakonczony. Wysylanie obrazka");
	argList resp;
	resp.set("msg", "ok");
	resp.set("type", "sendimage");
	
	emit(sendResponse(resp, scene));
}

/*
 * Zamiana ścieżek w pliku XML
 */
void connFunc::yafray_prepareFile() {
	// Plik źródłowyXML:
	QFile fp(scene);
	
	// Plik docelowy XML z zamienioną ścieżką
	QString filename = TEMP_DIR + "/netRayt_" + connThread::randomName();
	QFile fp2(filename);
	
	if (!fp.open(QIODevice::ReadOnly)) {
		qDebug("connFunc::yafray_prepareFile: Nie mozna otworzyc pliku ze scena");
		return;
	}
	
	if (!fp2.open(QIODevice::WriteOnly)) {
		qDebug("connFunc::yafray_prepareFile: Nie mozna utworzyc nowego pliku ze scena");
		return;
	}
	
	// rozmiar pliku XML i ilosc odczytanych danych
	int fileSize = fp.size();
	int dataSize = 0;
	
	// Odczytywanie lina po lini z pliku xml
	while (1) {
		char buff[1025];
		int bytes = fp.readLine(buff, 1024);
		
		// Dopisz ilosc odczytanych bajtow
		dataSize += bytes;
		
		// Sprawdz czy wyszukiwana linia to <output 
		QString line = buff;
		QRegExp rx(".*outfile value=\\\"(.*)\\\".*");
		if (rx.exactMatch(buff)) {
			QString path = rx.cap(1);
			line.replace(path, filename);
			
			qDebug(QString("connFunc::yafray_prepareFile: Zamiana sciezki z %1 na %2").arg(path, filename).toAscii());
		}
		
		// Zapisz linie do pliku
		fp2.write(line.toAscii(), line.size());
		
		// Sprawdz czy juz jest koniec pliku
		if (dataSize >= fileSize) {
			break;
		}
	}
	
	// Zamien nazwe pliku ze sceną na nowa
	scene = filename;
	fp.close();
	fp2.close();
}

#endif
